package cn.micai.base.asyn;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

/**
 * 描述：Java 7在java.util.concurrent包下加入了支持fork/join框架的RecursiveTask，forkjoinpool

 例子，去计算从start到end的连续数字的和：

 1）执行任务的类要继承RecursiveTask类

 2）定义一个compute方法，将要算的数分成两组，再分别调用compute方法去算。 运用了递归算法

 3）定义一个ForkJoinPool去执行任务， submit方法返还一个Future类， 通过future.get()去获取任务结果
 * <p>
 *
 * @author: 赵新国
 * @date: 2018/5/25 15:52
 */
public class J7ForkJoin extends RecursiveTask {

    private static final int THRESHOLD=5;
    private int beginning;
    private int ending;

    public J7ForkJoin(int beginning, int ending) {
        this.beginning = beginning;
        this.ending = ending;
    }

    @Override
    protected Integer compute() {
        // check if still need fork
        int sum = 0;
        boolean canCompute = (ending-beginning)<=THRESHOLD;
        if (canCompute) {
            // no need
            System.out.println("no need fork, ThreadID="+Thread.currentThread().getId());
            System.out.println("no need fork, beginning="+this.beginning);
            System.out.println("no need fork, ending="+this.ending);
            for (int i=beginning; i<=ending; i++) {
                sum += i;
            }
            return sum;
        } else {
            // need
            int interim = (this.ending+this.beginning)/2;
            //5+1 /2 =3 1-3
            //6+1 /2 =3 1-3
            System.out.println("need fork, ThreadID="+Thread.currentThread().getId());
            System.out.println("need fork, interim="+interim);
            J7ForkJoin leftTask = new J7ForkJoin(this.beginning , interim);
            J7ForkJoin rightTask = new J7ForkJoin(interim+1, this.ending);
            //.fork
            leftTask.fork();
            rightTask.fork();

            //get result
            int leftResult = (int) leftTask.join();
            int rightResult = (int) rightTask.join();
            sum = leftResult + rightResult;
            return sum;
        }
    }

    public static void main(String [] args) {
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        J7ForkJoin j7ForkJoin = new J7ForkJoin(1, 20);
        ForkJoinTask result = forkJoinPool.submit(j7ForkJoin);
        try {
            System.out.println("main result=" + result.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}
